package io.github.wanggit.antrpc.commons.bean;

import io.github.wanggit.antrpc.commons.utils.ArrayClassNameUtil;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.DigestUtils;

import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Data
public class RegisterBeanMethod implements Serializable {

    private static final long serialVersionUID = 2156942813066389334L;
    private String className;

    private String methodName;

    private List<String> parameterTypeNames;

    private int limit;

    private int durationInSeconds;

    private String methodId;

    private String humanFullName;

    public void generateMethodId() {
        StringBuilder buffer = new StringBuilder(methodName);
        for (String parameterTypeName : parameterTypeNames) {
            buffer.append(parameterTypeName);
        }
        methodId = DigestUtils.md5DigestAsHex(buffer.toString().getBytes(StandardCharsets.UTF_8));
    }

    public void generateFullName() {
        // 清理一下参数类型
        List<String> types = new ArrayList<>(parameterTypeNames.size());
        parameterTypeNames.forEach(
                it -> types.add(ArrayClassNameUtil.javaArrayNameToHumanName(it)));
        humanFullName = methodName + "(" + StringUtils.join(types, ", ") + ")";
    }

    @Override
    public String toString() {
        return methodName
                + "("
                + (null == parameterTypeNames ? "" : StringUtils.join(parameterTypeNames, ","))
                + ")";
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof RegisterBeanMethod)) {
            return false;
        }
        RegisterBeanMethod other = (RegisterBeanMethod) obj;
        return Objects.equals(className, other.getClassName())
                && Objects.equals(methodName, other.getMethodName())
                && Objects.equals(
                        parameterTypeNames.toString(), other.getParameterTypeNames().toString())
                && limit == other.getLimit()
                && durationInSeconds == other.getDurationInSeconds();
    }

    @Override
    public int hashCode() {
        return className.hashCode() + toString().hashCode() + limit + durationInSeconds;
    }
}
